package com.woniuxy.springcloud.consumer.student.controller;

import com.github.pagehelper.PageInfo;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.woniuxy.springcloud.common.entity.PageDto;
import com.woniuxy.springcloud.common.entity.ResponseResult;
import com.woniuxy.springcloud.common.entity.Student;
import com.woniuxy.springcloud.consumer.student.feignclient.StudentFeignClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

/**
 * description: ConsumerStudentController <br>
 * date: 2022/1/20 3:53 下午 <br>
 * author: shesaifei <br>
 * version: 1.0 <br>
 */
//@DefaultProperties(defaultFallback = "consumerStudentFallback") //统一降级方法的注解

//自动刷新注解,一定要添加到controller上
@RefreshScope
@Slf4j
@RestController
@RequestMapping("/consumerstudent")
public class ConsumerStudentController {
//    @Autowired
//    RestTemplate restTemplate;

    //使用Ribbon的方式
//    String getUrl() {
//        //Ribbon的本质就是restTemplate+@LoadBlanced,自动去注册中心通过名字获取调用地址
//        return "http://provider-student/student/";
//    }

//    @Autowired
//    DiscoveryClient discoveryClient;

    //String url = "http://localhost:8081/student/";

    //目前使用的调用方式是:RestTemplate+注册中心
//    String getUrl() {
//        List<ServiceInstance> instances = discoveryClient.getInstances("provider-student");
//        ServiceInstance serviceInstance = instances.get(0);
//        return "http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + "/student/";
//    }

    //OpenFeign使用

    @Resource
    StudentFeignClient studentFeignClient;


    @GetMapping("/{sid}")
    public ResponseResult<Student> getStudentBySid(@PathVariable("sid") int sid) {
        //restTemplate的API实现get远程调用
        //return restTemplate.getForObject(getUrl() + sid, ResponseResult.class);
        //OpenFeign使用
        return studentFeignClient.getStudent(sid);
    }

    @GetMapping("/")
    public ResponseResult<List<Student>> getAllStudent() {
        //return restTemplate.getForObject(getUrl(), ResponseResult.class);
        return studentFeignClient.getAllStudent();
    }

    @PostMapping("/")
    public ResponseResult addStudent(@RequestBody Student student) {
        log.info("student:" + student);
        //restTemplate的API实现post远程调用
        // return restTemplate.postForObject(getUrl(), student, ResponseResult.class);
        return studentFeignClient.addStudent(student);
    }
    //分页查询

    @PostMapping("/findAllStudent")
    public ResponseResult<PageInfo<Student>> findAllStudent(@RequestBody PageDto pageDto) {
        // return restTemplate.postForObject(getUrl() + "findAllStudent", pageDto, ResponseResult.class);
        return studentFeignClient.findAllStudent(pageDto);
    }

    //正常的
    @GetMapping("/ok")
    public ResponseResult<String> ok() {
        return studentFeignClient.ok();
    }


    //超时控制异常的
    //定义当前方法如何让出现异常，执行降级方法，降级方法和原来的方法的签名一致(访问修饰符，返回值，参数列表)
    //@HystrixCommand(fallbackMethod = "timeoutFallback")
    //统一降级的方法

    //@HystrixCommand
    @GetMapping("/timeout")
    public ResponseResult<String> timeout() {
        //版本1
        //使用超时模拟异常
//        try {
//            return studentFeignClient.timeout();
//        }catch (Exception e){
//            return new ResponseResult<String>(500,"exception","timeout-exception");
//        }

        //版本2
        System.out.println("进入timeout");
        return studentFeignClient.timeout();

    }

//    public ResponseResult<String> timeoutFallback() {
//        System.out.println("进入timeoutFallback");
//        return new ResponseResult<String>(500, "fallback", "timeout-fallback");
//    }

    //统一的降级方法
    //实现统一的降级方法(缺点：方法签名要统一不好满足)

    //    public ResponseResult<String> consumerStudentFallback() {
//        System.out.println("进入consumerStudentFallback");
//        return new ResponseResult<String>(500, "consumerStudentFallback", "consumerStudentFallback");
//    }
    @HystrixCommand(fallbackMethod = "testfallback", commandProperties = {
            //开启降级
            @HystrixProperty(name = "circuitBreaker.enabled", value = "true"),
            //请求个数
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),
            //配置时间窗(毫秒)
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"),
            //指定错误率（错误的百分比）
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60"),
    })
    @RequestMapping("/test/{id}")
    public ResponseResult<String> test(@PathVariable("id") int id) {
        if (id < 1) {
            throw new RuntimeException("test exception");
        }
        return new ResponseResult<String>(200, "test-ok", "test-ok");
    }

    public ResponseResult<String> testfallback() {
        return new ResponseResult<String>(200, "testfallback", "testfallback");
    }

    @Value("${testconfig}")
    String testconfig;

    @GetMapping("/testconfig")
    public ResponseResult<String> testconfig() {
        return new ResponseResult<String>(200, "testconfig", testconfig);
    }
}
